---
title: 桥接模式
description: Bridge Pattern - 将抽象部分与实现部分分离，使它们都可以独立地变化
sidebar_position: 1
---

# 桥接模式

桥接模式（Bridge Pattern）是一种结构型设计模式，其核心思想是**将抽象部分与实现部分分离，使它们都可以独立地变化**。

## 模式概述

### 解决的问题

传统多层继承存在的问题：
- **继承爆炸**：类的数量呈指数级增长
- **维护困难**：继承层次过深，难以理解和维护
- **违反原则**：违背单一职责原则和开闭原则

### 核心思想

桥接模式通过**组合关系替代继承关系**，将两个独立变化的维度解耦，实现更灵活的系统设计。

:::tip 关键洞察
桥接模式巧妙地将多层继承问题转换为组合问题，通过抽象关联来取代传统的多层继承，将类之间的静态继承关系变为动态的组合关系，有效控制了系统中类的个数，避免了继承层次的指数级爆炸。
:::

## 模式结构

### 核心角色

1. **抽象化角色（Abstraction）**
   - 定义抽象接口
   - 包含对实现化对象的引用
   - 负责定义角色的行为

2. **扩展抽象化角色（RefinedAbstraction）**
   - 抽象化角色的子类
   - 实现具体的抽象行为

3. **实现化角色（Implementor）**
   - 定义实现接口
   - 供扩展抽象化角色调用

4. **具体实现化角色（ConcreteImplementor）**
   - 实现化角色的具体实现

### 关系特点

**抽象化角色和实现化角色是组合关系，桥接模式最大的特点就是抽象角色引用实现角色。**

## 模式原理

### 现实问题

![](https://wkq-img.oss-cn-chengdu.aliyuncs.com/site/20250805121007.png)

### 蜡笔 vs 毛笔的对比

从图中可以看出：
- **蜡笔：3 × 12 = 36支** - 需要36个类，不适合桥接模式
- **毛笔：3 + 12（调色板）** - 只需要15个类，适合桥接模式

**蜡笔不适合桥接模式的原因：**
- 颜色是蜡笔的固有属性，无法分离
- 型号和颜色是强耦合关系
- 无法通过组合方式解耦

**毛笔适合桥接模式的原因：**
- 毛笔本身不包含颜色，颜色通过外部调色板提供
- 型号和颜色是两个独立变化的维度
- 可以通过组合关系实现灵活的多维度变化

### 角色关系图

![](https://wkq-img.oss-cn-chengdu.aliyuncs.com/site/20250805230903.png)

### 经典示例：毛笔系统

以毛笔系统为例说明桥接模式：

- **抽象化角色**：毛笔
- **扩展抽象化角色**：大号毛笔、中号毛笔、小号毛笔
- **实现化角色**：颜色接口
- **具体实现化角色**：黑色、红色、蓝色等

毛笔的型号和颜色是两个独立变化的维度，通过桥接模式实现了实体与行为的分离，将需要多层继承的场景转换为组合的方式。

![](https://wkq-img.oss-cn-chengdu.aliyuncs.com/site/20250805231504.png)

:::info 设计本质
桥接模式的核心是对变化维度进行分类和抽象，通过组合关系实现灵活的多维度变化。
:::

## 实际应用示例

### 支付系统场景

模拟不同的支付工具对应不同的支付模式：
- **支付渠道**：微信、支付宝
- **支付方式**：密码支付、人脸支付、指纹支付

![](https://wkq-img.oss-cn-chengdu.aliyuncs.com/site/20250805231957.png)

### 传统方式的问题

```java
package com.e6yun.project.structural.bridge;

import java.math.BigDecimal;

/**
 * 支付控制器 - 传统方式
 */
public class PayController {

  /**
   * 支付功能
   *
   * @param uId         用户id
   * @param tradeId     交易id
   * @param amount      交易金额
   * @param channelType 渠道类型 1 微信  2 支付宝
   * @param modeType    支付类型 1 密码  2 人脸  3 指纹
   * @return boolean
   */
  public boolean doPay(String uId, String tradeId, BigDecimal amount, Integer channelType,
      Integer modeType) {
    // 微信支付
    if (channelType == 1) {
      System.out.println("微信渠道支付开始...");
      if (1 == modeType) {
        System.out.println("密码支付...");
      } else if (2 == modeType) {
        System.out.println("人脸支付...");
      } else if (3 == modeType) {
        System.out.println("指纹支付");
      }
    }
    // 支付宝支付
    if (channelType == 2) {
      System.out.println("支付宝渠道支付开始...");
      if (1 == modeType) {
        System.out.println("密码支付...");
      } else if (2 == modeType) {
        System.out.println("人脸支付...");
      } else if (3 == modeType) {
        System.out.println("指纹支付");
      }
    }
    return true;
  }
}
```

**传统方式的问题：**
- 代码重复严重
- 难以扩展（新增渠道或支付方式需要修改多处）
- 违反开闭原则
- 维护成本高

### 桥接模式重构

**核心思路：识别两个独立变化维度，设计两个独立的继承等级结构，建立抽象耦合。**

#### 1. 实现化角色（支付方式）

```java
/**
 * 支付方式接口 - 实现化角色
 */
public interface IPayMode {
    boolean security(String uId);
}

/**
 * 密码支付 - 具体实现化角色
 */
public class PayCypher implements IPayMode {
    @Override
    public boolean security(String uId) {
        System.out.println("密码支付");
        return true;
    }
}

/**
 * 人脸支付 - 具体实现化角色
 */
public class PayFaceMode implements IPayMode {
    @Override
    public boolean security(String uId) {
        System.out.println("人脸支付");
        return true;
    }
}

/**
 * 指纹支付 - 具体实现化角色
 */
public class PayFingerprintMode implements IPayMode {
    @Override
    public boolean security(String uId) {
        System.out.println("指纹支付");
        return true;
    }
}
```

#### 2. 抽象化角色（支付渠道）

```java
/**
 * 支付抽象类 - 抽象化角色
 */
public abstract class Pay {
    protected IPayMode payMode;

    public Pay(IPayMode payMode) {
        this.payMode = payMode;
    }

    public abstract String transfer(String uId, String tradeId, BigDecimal amount);
}

/**
 * 微信支付 - 扩展抽象化角色
 */
public class WxPay extends Pay {
    public WxPay(IPayMode payMode) {
        super(payMode);
    }

    @Override
    public String transfer(String uId, String tradeId, BigDecimal amount) {
        System.out.println("微信渠道支付");
        boolean security = payMode.security(uId);
        return "0000";
    }
}

/**
 * 支付宝支付 - 扩展抽象化角色
 */
public class ZfbPay extends Pay {
    public ZfbPay(IPayMode payMode) {
        super(payMode);
    }

    @Override
    public String transfer(String uId, String tradeId, BigDecimal amount) {
        System.out.println("支付宝渠道支付");
        boolean security = payMode.security(uId);
        return "0000";
    }
}
```

#### 3. 客户端使用

```java
/**
 * 桥接模式客户端
 */
public class PayController {

    public boolean doPay(String uId, String tradeId, BigDecimal amount, Integer channelType,
                        Integer modeType) {
        // 根据支付方式创建对应的实现
        IPayMode payMode = null;
        if (modeType == 1) {
            payMode = new PayCypher();
        } else if (modeType == 2) {
            payMode = new PayFaceMode();
        } else if (modeType == 3) {
            payMode = new PayFingerprintMode();
        }

        // 根据渠道创建对应的支付对象
        Pay pay = null;
        if (channelType == 1) {
            pay = new WxPay(payMode);
        } else if (channelType == 2) {
            pay = new ZfbPay(payMode);
        }

        return pay.transfer(uId, tradeId, amount) != null;
    }
}
```

### 重构后的优势

1. **解耦抽象与实现**：支付渠道和支付方式可以独立变化
2. **避免继承爆炸**：传统方式需要 2×3=6 个类，桥接模式只需要 2+3=5 个类
3. **易于扩展**：新增渠道或支付方式不会影响现有代码
4. **符合设计原则**：开闭原则、单一职责原则、依赖倒置原则

![](https://wkq-img.oss-cn-chengdu.aliyuncs.com/site/20250805233958.png)

## 模式总结

### 优点

1. **解耦抽象与实现**
   - 使用对象间的关联关系解耦抽象和实现
   - 抽象和实现可以沿着各自的维度独立变化

2. **替代多层继承**
   - 避免继承层次的指数级爆炸
   - 提高代码复用性和可维护性

3. **提高系统扩展性**
   - 在两个变化维度中任意扩展一个维度都不需要修改原有系统
   - 符合开闭原则

:::tip 核心优势
桥接模式将类分为两个维度：实体维度（支付渠道）和功能维度（支付方式）。抽象化角色和实现化角色通过组合关系连接，实现了灵活的多维度变化。
:::

### 缺点

1. **增加设计复杂度**
   - 要求开发者一开始就要对抽象层进行设计和编程
   - 增加了系统的理解和设计难度

2. **需要丰富经验**
   - 要求正确识别出系统中的两个独立变化维度
   - 维度的划分需要相当丰富的经验

### 使用场景

1. **平台独立性应用**
   - 不同数据库的 JDBC 驱动程序
   - 硬盘驱动程序

2. **统一协议下的多组件**
   - 支付场景中的各种支付渠道
   - 统一协议是收款、支付、扣款，组件是微信、支付宝等

3. **消息驱动场景**
   - 手机短信、邮件消息、QQ 消息、微信消息等
   - 消息行为统一（发送、接收、处理、回执），但具体实现各不相同

4. **复杂类拆分**
   - 当一个类中包含大量的对象和方法时
   - 既不方便阅读，也不方便修改

5. **多维度扩展**
   - 系统功能性和非功能性角度
   - 业务或技术角度等

### 与其他模式的区别

- **与适配器模式**：桥接模式是设计时考虑的结构，适配器模式是解决已有代码的兼容性问题
- **与策略模式**：桥接模式关注抽象与实现的分离，策略模式关注算法的选择
- **与装饰器模式**：桥接模式是静态的结构设计，装饰器模式是动态的功能扩展
